#!/usr/bin/python3
'''
    Randpic is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
'''
import gi
import os
import random
import subprocess
import copy
import time
import threading
import glob
from distutils.spawn import find_executable

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

# Doesn't search for webp and other formats images

def is_int(s):
    try:
        int(s)
        return True
    except ValueError:
        return False
def get_icon(file_path):
    dir_of_py_file = os.path.dirname(__file__)
    rel_path_to_resource = os.path.join(dir_of_py_file, file_path)
    abs_path_to_resource = os.path.abspath(rel_path_to_resource)
    return abs_path_to_resource

class FileChooserWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Randpic")
        self.folder = ""
        self.images = ""
        self.minutes = ""
        self.seconds = ""
        self.all_images = ""
        self.openned_new = False
        self.set_resizable(False)
        self.set_icon_from_file(get_icon("icon.png"))
        # Show as a vertical box.

        vbox = Gtk.Box(orientation = Gtk.Orientation.VERTICAL)
        self.add(vbox)

        # Create horizontal box with draw time inputs

        hbox_time = Gtk.Box()
        hbox_time.set_spacing(10)
        label_draw_time = Gtk.Label(label="Draw time")
        self.minutes_entry = Gtk.Entry(text="00")

        label_time = Gtk.Label(label=":")
        self.seconds_entry = Gtk.Entry(text="00")
        self.minutes_entry.set_width_chars(2)
        self.seconds_entry.set_width_chars(2)
        hbox_time.add(label_draw_time)
        hbox_time.add(self.minutes_entry)
        hbox_time.add(label_time)
        hbox_time.add(self.seconds_entry)

        # Show horizontal box

        vbox.add(hbox_time)

        # Create horizontal box with draw time inputs

        hbox_buttons = Gtk.Box()

        button1 = Gtk.Button(label="Choose Files")
        button1.connect("clicked", self.on_file_clicked)

        button2 = Gtk.Button(label="Choose Folder")
        button2.connect("clicked", self.on_folder_clicked)

        button3 = Gtk.Button(label="Confirm")
        button3.connect("clicked", self.confirm_clicked)

        hbox_buttons.add(button1)
        hbox_buttons.add(button2)
        hbox_buttons.add(button3)

        # Show horizontal box

        vbox.add(hbox_buttons)

    def confirm_clicked(self, widget):
        if(not is_int(self.minutes_entry.get_text()) or not is_int(self.seconds_entry.get_text())):
            print("Draw time must be a number")

        elif(int(self.minutes_entry.get_text()) < 0 or int(self.seconds_entry.get_text()) < 0):
            print("Draw time must be bigger than 0 or equal")

        elif(self.images != ""):



            self.all_images = copy.deepcopy(self.images)
            self.minutes = int(self.minutes_entry.get_text())
            self.seconds = int(self.seconds_entry.get_text())
            win = Buttons(self.all_images, self.minutes, self.seconds)
            win.connect("destroy", Gtk.main_quit)
            win.show_all()
            self.openned_new = True
            self.destroy()

        elif(self.folder != ""):
            self.all_images = [img for img in glob.glob(self.folder + "/*.jpg")] + [img for img in glob.glob(self.folder + "/*.png")]

            self.minutes = int(self.minutes_entry.get_text())
            self.seconds = int(self.seconds_entry.get_text())
            win = Buttons(self.all_images, self.minutes, self.seconds)

            win.connect("destroy", Gtk.main_quit)

            win.show_all()
            self.openned_new = True
            self.destroy()

        else:
            print("Choose wisely but at least choose")

    def on_file_clicked(self, widget):
        dialog = Gtk.FileChooserDialog(
            title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN
        )

        dialog.add_buttons(
            Gtk.STOCK_CANCEL,
            Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OPEN,
            Gtk.ResponseType.OK,
        )

        dialog.set_select_multiple(True)
        self.add_filters(dialog)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:

            print("Open clicked")
            listi = dialog.get_filenames()

            i = 0
            while(i < len(listi)):
                print("File selected: " + listi[i])
                i += 1

            self.images = dialog.get_filenames()

        elif response == Gtk.ResponseType.CANCEL:
            print("Cancel clicked")

        dialog.destroy()

    def add_filters(self, dialog):
        filter_text = Gtk.FileFilter()
        filter_text.set_name("Images files")
        filter_text.add_mime_type("image/png")
        filter_text.add_mime_type("image/jpeg")
        dialog.add_filter(filter_text)

        filter_any = Gtk.FileFilter()
        filter_any.set_name("Any files")
        filter_any.add_pattern("*")
        dialog.add_filter(filter_any)

    def on_folder_clicked(self, widget):
        dialog = Gtk.FileChooserDialog(
            title="Please choose a folder",
            parent=self,
            action=Gtk.FileChooserAction.SELECT_FOLDER,
        )
        dialog.add_buttons(
            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, "Select", Gtk.ResponseType.OK
        )
        dialog.set_default_size(800, 400)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("Select clicked")
            print("Folder selected: " + dialog.get_filename())
            self.folder = dialog.get_filename()

        elif response == Gtk.ResponseType.CANCEL:
            print("Cancel clicked")

        dialog.destroy()

    def destroy_first(self, gtkobject, data=None):
        if(not self.openned_new):
            Gtk.main_quit()

def terminal_command(file_path):
    """Open image viewer with image in file_path"""

    test_eom = subprocess.Popen(['xdg-open "' + file_path + '"' ], shell=True)
    return test_eom

def is_tool(name):
    """Check whether `name` is on PATH."""

    return find_executable(name) is not None

def kill_all():
    if(is_tool("eom")):
        os.system("killall eom")
    elif(is_tool("eog")):
        os.system("killall eog")

class Buttons(Gtk.Window):

    def __init__(self, all_images, minutes, seconds):

        Gtk.Window.__init__(self, title="Randpic")
        self.all_images = all_images
        self.random_images = copy.deepcopy(all_images)
        self.start_seconds = seconds
        self.start_minutes = minutes
        self.running = True
        self.set_resizable(False)
        self.set_icon_from_file(get_icon("icon.png"))
        s = self.random_without_repeated()
        self.program = terminal_command(s)
        self.endless_time = False
        if(self.start_seconds == 0 and self.start_minutes == 0):
            self.endless_time = True
        # Create horizontal box with draw time inputs

        box = Gtk.Box()
       	self.add(box)

        # Create widgets

        button2 = Gtk.Button(label="Play")
        button2.connect("clicked", self.play_clicked)

        self.minutes_entry = Gtk.Label(label="00")
        label2 = Gtk.Label(label=":")
        self.seconds_entry = Gtk.Label(label="00")

        button3 = Gtk.Button(label="Pause")
        button3.connect("clicked", self.pause_clicked)
        button4 = Gtk.Button(label="Next")
        button4.connect("clicked", self.next_clicked)

        # Show widgets

        box.add(button2)
        box.add(self.minutes_entry)
        box.add(label2)
        box.add(self.seconds_entry)
        box.add(button3)
        box.add(button4)

        # Start background countdown

        thread = threading.Thread(target=self.countdown, args=(minutes, seconds))
        thread.daemon = True
        thread.start()

    def random_without_repeated(self):
        s = random.choice(self.random_images)
        self.random_images.remove(s)
        if(len(self.random_images) == 0):
            self.random_images = copy.deepcopy(self.all_images)
        return s

    def countdown(self, minutes, seconds):
        ''' Background countdown and updates UI '''
        if(not self.endless_time):
            t = minutes * 60 + seconds
            while (t > 0 and self.running): 
                mins, secs = divmod(t, 60)
                self.minutes_entry.set_text(str(mins))
                self.seconds_entry.set_text(str(secs))
                time.sleep(1) 
                t -= 1
            if(t <= 0):
                self.next_image()

    def play_clicked(self, widget):
        if(not self.running):
            self.running = True
            self.throw_countdown_thread(int(self.minutes_entry.get_text()), int(self.seconds_entry.get_text()))

        self.running = True

    def pause_clicked(self, widget):
        self.running = False

    def next_clicked(self, widget):
        self.next_image()

    def next_image(self):
        self.program.kill()
        s = self.random_without_repeated()
		
        kill_all()
        
        ''' Wait until others process stop '''
        self.running = False
        time.sleep(1.1)

        ''' Start a new one '''

        self.running = True
        self.program = terminal_command(s)
        self.throw_countdown_thread(self.start_minutes, self.start_seconds)

    def throw_countdown_thread(self, minutes, seconds):
        thread = threading.Thread(target=self.countdown, args=(minutes, seconds))
        thread.daemon = True
        thread.start()

win = FileChooserWindow()
win.connect("destroy", win.destroy_first)
win.show_all()
Gtk.main()
